package client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.LinkedList;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JToolBar;


import metier.modele.Client;
import metier.modele.Constantes;
import metier.modele.Figure;
import metier.outils.ExportBMP;
import metier.outils.ExportSvg;
import metier.outils.Tools;
import metier.outils.Tools_Edit;


public class Gestionnaire_Client implements MouseListener, MouseMotionListener,
		KeyListener, ActionListener {


	private JFrame fen;
	private JCanvas jCanvas;
	private panUsers panUsers;
	
	private JPanel panelSouth, panelWest, panelPreviewBG, panelPreviewFG;
	private JMenuBar barreMenus;
	private JMenu fichier, affichage, connexion, exporter; // Composantes {Niveau 1}.
	private JMenuItem nouveau, quitter, export_SVG, export_BITMAP; 
	
	private JMenuItem connexionItem;
	private JRadioButtonMenuItem couleursRelles, couleursUtilisateur;
	private ButtonGroup choixCouleurs;
	private JToolBar barreOutils, barreDessin;
	private JButton deleteB, rectangleB, ellipseB, traitB, mainB, editB,
			currentTool;
	private JButton couleursFG, couleursBG;
	private Client client;
	private boolean couleursVraies;

	private Color colorPickedFG = Color.BLACK;
	private Color colorPickedBG = Color.WHITE;

	private LinkedList<Figure> listFig;
	
	private boolean drawSquare = false;
	
	int WIDTH = 640;
	int HEIGHT = 480;
	int PANEL_PREVIEW_SIZE = 30;

	
	/**
	 * Constructeur
	 * @param IP
	 * @param port
	 * @param pseudo
	 * @param online
	 */
	public Gestionnaire_Client(String IP, int port, String pseudo,
			final boolean online) {

		listFig = new LinkedList<Figure>(); // Liste de figures.

		fen = new JFrame(Constantes.CLIENT_TITLE);
		fen.setSize(WIDTH, HEIGHT);
		fen.setLocationRelativeTo(null);

		// Gestionnaire de mise en forme.
		BorderLayout bl = new BorderLayout();
		fen.getContentPane().setLayout(bl);

		jCanvas = new JCanvas(this, WIDTH, HEIGHT, listFig);
		fen.getContentPane().add(jCanvas, BorderLayout.CENTER);
		jCanvas.addMouseListener(this);
		jCanvas.addMouseMotionListener(this);

		// Barre de menus.
		barreMenus = new JMenuBar();
		fen.setJMenuBar(barreMenus);

		// Fichier.
		fichier = new JMenu("Fichier");
		fichier.setMnemonic('F');
		barreMenus.add(fichier);

		// Nouveau.
		nouveau = new JMenuItem("Nouveau", new ImageIcon(this.getClass().getResource("/img/menu/1.gif")));
		nouveau.addActionListener(this);
		fichier.add(nouveau);

		fichier.addSeparator();

		// Exporter
		exporter = new JMenu("Exporter");
		exporter.setMnemonic('E');
		fichier.add(exporter);
		
			// Exporter => SVG
			export_SVG = new JMenuItem("SVG");
			export_SVG.addActionListener(this);
			export_SVG.setEnabled(true);
			export_SVG.setFocusable(true);
			exporter.add(export_SVG);
			
			// Exporter => BITMAP
			export_BITMAP = new JMenuItem("BMP");
			export_BITMAP.addActionListener(this);
			export_BITMAP.setEnabled(true);
			export_BITMAP.setFocusable(true);
			exporter.add(export_BITMAP);
			

		fichier.addSeparator();

		// Quitter.
		quitter = new JMenuItem("Quitter", new ImageIcon(this.getClass().getResource("/img/menu/4.gif")));
		quitter.addActionListener(this);
		fichier.add(quitter);

		// Affichage.
		affichage = new JMenu("Affichage");
		affichage.setMnemonic('A');
		barreMenus.add(affichage);
		affichage.setEnabled(false);

		
		// Selection couleurs figures
		choixCouleurs = new ButtonGroup();
		couleursRelles = new JRadioButtonMenuItem("Couleurs réelles");
		couleursRelles.setSelected(true);
		couleursVraies = true;
		couleursUtilisateur = new JRadioButtonMenuItem("Couleurs / utilisateur");
		couleursRelles.addActionListener(this);
		couleursUtilisateur.addActionListener(this);
		choixCouleurs.add(couleursRelles);
		choixCouleurs.add(couleursUtilisateur);
		affichage.add(couleursRelles);
		affichage.add(couleursUtilisateur);

		// Connexion
		connexion = new JMenu("Connexion");
		connexion.setMnemonic('C');
		barreMenus.add(connexion);

		connexionItem = new JMenuItem("Se connecter à un serveur ...",
				new ImageIcon(this.getClass().getResource("/img/menu/3.gif")));
		connexionItem.addActionListener(this);
		connexion.add(connexionItem);

		// Barre d'outils.
		barreOutils = new JToolBar();
		barreOutils.setFloatable(false);

		// Création des boutons (couleurs)

		panelSouth = new JPanel();

			// FG
			panelPreviewFG = new JPanel();
			panelPreviewFG.setPreferredSize(new Dimension(PANEL_PREVIEW_SIZE, PANEL_PREVIEW_SIZE));
			panelPreviewFG.setBackground(colorPickedFG);
			panelSouth.add(panelPreviewFG);
		
			couleursFG = new JButton("Contour");
			couleursFG.addActionListener(this);
			panelSouth.add(couleursFG);
			
			
			// BG
			panelPreviewBG = new JPanel();
			panelPreviewBG.setPreferredSize(new Dimension(PANEL_PREVIEW_SIZE, PANEL_PREVIEW_SIZE));
			panelPreviewBG.setBackground(colorPickedBG);
			panelSouth.add(panelPreviewBG);
			
			couleursBG = new JButton("Remplissage");
			couleursBG.addActionListener(this);
			panelSouth.add(couleursBG);
		

		fen.getContentPane().add(panelSouth, BorderLayout.SOUTH);
		
		
		// Création de la barre d'outils de dessin.

		barreDessin = new JToolBar();
		barreDessin.setFloatable(false);
		fen.getContentPane().add(barreDessin, BorderLayout.NORTH);
		
		// / Liste des utilisateurs
		panUsers = new panUsers();
		
		client = new Client(IP, port, this, pseudo);

		if (online == true) // Travail online ?
		{
			if (client.creationClient() == true) // On est connect� !
			{
				// / Liste des utilisateurs
				client.getCnx().Envoie(client.getUser()); // Envoie de l'utilsateur
				fen.add(panUsers, BorderLayout.EAST);
				affichage.setEnabled(true);
				client.setOnline(true);
			}
			else // Pop-up => Travail hors ligne car serveur ne répond pas
			{ 
				client.setOnline(false);
				JOptionPane
						.showMessageDialog(
								null,
								Constantes.CLIENT_FAIL_CONNECT,
								Constantes.CLIENT_FAIL_CONNECT_TITLE,
								JOptionPane.WARNING_MESSAGE);
			}
		}


			editB = new Tools_Edit(client, this, jCanvas,
					"Edition", new ImageIcon(this.getClass().getResource("/img/outils/main.jpg")));
			deleteB = new Createur(client, this, "metier.outils.Tools_Delete",
					jCanvas, "Gomme", new ImageIcon(this.getClass().getResource("/img/outils/gomme.jpg")));
			rectangleB = new Createur(client, this,	"metier.outils.Tools_Rect", 
					jCanvas, "Rectangle", new ImageIcon(this.getClass().getResource("/img/outils/rectangle.jpg")));
			ellipseB = new Createur(client, this, "metier.outils.Tools_Ellipse",
					jCanvas, "Ellipse", new ImageIcon(this.getClass().getResource("/img/outils/ellipse.jpg")));
			traitB = new Createur(client, this, "metier.outils.Tools_Trait",
					jCanvas, "Trait", new ImageIcon(this.getClass().getResource("/img/outils/trait.jpg")));
			mainB = new Createur(client, this, "metier.outils.Tools_Main",
					jCanvas, "Main levée", new ImageIcon(this.getClass().getResource("/img/outils/main_levee.jpg")));


		currentTool = rectangleB; // Default tool;

		panelWest = new JPanel();
		panelWest.setPreferredSize(new Dimension(25, jCanvas.getHeight()));
		panelWest.setBorder(BorderFactory.createEtchedBorder());

		panelWest.add(editB);
		panelWest.add(deleteB);
		panelWest.add(rectangleB);
		panelWest.add(ellipseB);
		panelWest.add(traitB);
		panelWest.add(mainB);

		fen.add(panelWest, BorderLayout.WEST);

		// Fonction lors de la fermetrue de la fen�tre :
		fen.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				if (client.isOnline()) // On est en ligne ? On se déconnecte
				{
					client.fermetureClient();
				}
				System.exit(0);
			}
		});

		fen.setVisible(true);

	}

	/**
	 * Met à jour les couleurs (preview)
	 */
	public void updatePreviewColors()
	{
		panelPreviewBG.setBackground(colorPickedBG);
		panelPreviewFG.setBackground(colorPickedFG);
	}
	

	
	public void mousePressed(MouseEvent e) {
		jCanvas.setCurrentBg(colorPickedBG);
		jCanvas.setCurrentFg(colorPickedFG);

		Tools o = (Tools) currentTool;
		if (o != null)
			o.debutClic(e);
		else
			System.out.println("Erreur, outils 'currentTool' null!");
	}

	public void mouseReleased(MouseEvent e) {
		try{
		Tools o = (Tools) currentTool;
		
			o.finClic(e);
		} catch (NullPointerException ex){
			JOptionPane.showMessageDialog(null,"Sélectionnez figure à supprimer","NullPointerException",JOptionPane.WARNING_MESSAGE);
		}
		
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseClicked(MouseEvent e) {
	}

	public void mouseDragged(MouseEvent e) {
		Tools o = (Tools) currentTool;
		if (o != null)
			o.pendantClic(e);
		else
			System.out.println("Erreur, outils 'currentTool' null!");

	}

	public void mouseMoved(MouseEvent e) {
	}
	
	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_SHIFT)
		{
			drawSquare = true;
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_SHIFT)
		{
			drawSquare = false;
		}
		else if (e.getKeyCode() == KeyEvent.VK_DELETE)
		{
			int i = 0;
			for (Figure f : jCanvas.getList()) {
				if (f.getStatus() == Figure.SUPPRESSION)
					break;
				i++;
			}
			if (i < jCanvas.getList().size())
			{
				if (client.isOnline()) {
					//jCanvas.getList().get(i).setStatus(Figure.AJOUT);
					client.getCnx().Envoie(jCanvas.getList().get(i));
				}
				else
				{
					jCanvas.getList().remove(i);
					jCanvas.repaint();
				}
			}
		}
	}
	
	@Override
	public void keyTyped(KeyEvent e) {
	}

	
	/**
	 * Détecte les clic sur tous les boutons / menus
	 */
	public void actionPerformed(ActionEvent e) 
	{
		Object source = e.getSource();

		// Nouveau :
		if (source == nouveau) 
		{

			// Popup : ARE YOU SURE ?????
			int question = JOptionPane
					.showConfirmDialog(
							null,
							Constantes.CLIENT_NEW_FILE,
							fen.getTitle(), JOptionPane.OK_CANCEL_OPTION);

			if (question == JOptionPane.OK_OPTION) {
				// On envoie la nouvelle liste au serveur pour la MAJ
				if (client.isOnline())
				{
					// TODO
					client.getCnx().Envoie(Constantes.INIT_DRAW);
				}
				else
				{
					jCanvas.setList(new LinkedList<Figure>());
				}

				// On met a jour la fenêtre.
				jCanvas.repaint();
			}
		}

		// Exporter => SVG
		if (source == export_SVG)
		{
			JFileChooser fc = new JFileChooser();
			fc.setCurrentDirectory (new File ("."));
			int returnVal = fc.showOpenDialog(null);
			if (returnVal == JFileChooser.APPROVE_OPTION)
			{
				File file = fc.getSelectedFile();
				ExportSvg es = new ExportSvg(file.toString(),jCanvas.getList());
				try {
					es.graphicToSVG();
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					JOptionPane.showMessageDialog(null,e1.getMessage(), "FileNotFound",JOptionPane.ERROR_MESSAGE);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					JOptionPane.showMessageDialog(null,e1.getMessage(), "IOException",JOptionPane.ERROR_MESSAGE);
					
				}
				JOptionPane.showMessageDialog(null, "L'image a bien été exportée en SVG!\n\n" + fc.getSelectedFile().toString());
			}
			
		}

		// Exporter => BITMAP
		if (source == export_BITMAP) 
		{
			JFileChooser fc = new JFileChooser();
			fc.setCurrentDirectory (new File ("."));
			int returnVal = fc.showOpenDialog(null);
			if (returnVal == JFileChooser.APPROVE_OPTION)
			{
				File file = fc.getSelectedFile();
				ExportBMP eBMP = new ExportBMP(file, jCanvas);
				boolean r = eBMP.export();
				if (r == true)
				{
					JOptionPane.showMessageDialog(null, "L'image a bien été exportée en BITMAP!\n\n" + fc.getSelectedFile().toString());
				}
				else
				{
					JOptionPane.showMessageDialog(null, "Une erreur est survenue lors de l'exportation!", "Erreur!", JOptionPane.ERROR_MESSAGE);
				}
			}
		}

	
		// Quitter :
		if (source == quitter)
		{
			if (client.isOnline())
				client.fermetureClient();
			System.exit(0);
		}

		if (source == couleursRelles)
		{
			couleursVraies = true;
			jCanvas.repaint();
		}

		if (source == couleursUtilisateur)
		{
			couleursVraies = false;
			jCanvas.repaint();
		}

		if (source == connexionItem)
		{
			int question = JOptionPane
					.showConfirmDialog(
							null,
							Constantes.CLIENT_NEW_CONNECT,
							fen.getTitle(), JOptionPane.OK_CANCEL_OPTION);

			if (question == JOptionPane.OK_OPTION)
			{
				fen.dispose();
				if (client.isOnline())
				{
					client.fermetureClient();
				}
				new Gestionnaire_Client_Connexion();
			}

		}
		
		
		if (source == couleursFG || source == couleursBG)
		{
			new ColorPicker(this, (source == couleursFG ? true : false));
		}
		

		if (source == deleteB || source == rectangleB || source == ellipseB
				|| source == traitB || source == mainB || source == editB)
			currentTool = (JButton) source;
		
		if (source == editB)
		{
			jCanvas.inEdit = true;
			jCanvas.repaint();
		}
		else
		{
			jCanvas.inEdit = false;
			jCanvas.repaint();
		}
		
		if (source != deleteB)
		{
			jCanvas.setAllFigureStatus(Figure.AJOUT);
		}

	}



	public boolean isCouleursVraies() {
		return couleursVraies;
	}

	public void setColorPickedFG(Color colorPickedFG) {
		this.colorPickedFG = colorPickedFG;
	}

	public void setColorPickedBG(Color colorPickedBG) {
		this.colorPickedBG = colorPickedBG;
	}

	public JCanvas getPanDessin() {
		return jCanvas;
	}

	public void setPanDessin(JCanvas panDessin) {
		this.jCanvas = panDessin;
	}

	public panUsers getPanUsers() {
		return panUsers;
	}

	public void setPanUsers(panUsers panUsers) {
		this.panUsers = panUsers;
	}

	public JFrame getFen() {
		return fen;
	}

	public void setFen(JFrame fen) {
		this.fen = fen;
	}
	
	public boolean isDrawSquare() {
		return drawSquare;
	}

}